#include <sys/types.h>  /* for type definitions */
#include <sys/socket.h> /* for socket API calls */
#include <netinet/in.h> /* for address structs */
#include <arpa/inet.h>  /* for sockaddr_in */
#include <stdio.h>      /* for printf() and fprintf() */
#include <stdlib.h>     /* for atoi() */
#include <string.h>     /* for strlen() */
#include <unistd.h>     /* for close() */
/* 
 * File:   main.c
 * Author: otaviokz
 *
 * Created on June 29, 2011, 1:16 AM
 */
#define MAXBUFFSIZE  1500

int main(int argc, char** argv)
{
    int status, sock, socklen;
    char buffer[MAXBUFFSIZE];
    struct sockaddr_in saddr;
    struct in_addr iaddr;
    unsigned char ttl = 3;
    unsigned char one = 1;
    
    //set content of of saddr and iaddr to zero
    memset(&saddr, 0, sizeof(struct sockaddr_in));
    memset(&iaddr, 0, sizeof(struct in_addr));
    
    //open UDP socket
    sock = socket(PF_INET, SOCK_DGRAM, 0);
    if(sock < 0)
        perror("Error creating socket"), exit(0);

    saddr.sin_family = PF_INET;
    saddr.sin_port = htons(0);
    saddr.sin_addr.s_addr = htonl(INADDR_ANY);
    status = bind(sock, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));

    if(status < 0)
        perror("Error binding socket to interface"), exit(0);

    iaddr.s_addr = INADDR_ANY;

    //set the outgoing interface to default
    setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, &iaddr, sizeof(struct in_addr));

    //set multicast packet ttl to 3
    setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(unsigned char));

    //set multicast traffic to myself too
    status = setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, &one, sizeof(unsigned char));

    //set destination multicast address
    saddr.sin_family = PF_INET;
    saddr.sin_addr.s_addr = inet_addr("192.168.0.104");
    saddr.sin_port = htons(4096);

    while(1)
    {
        //put some data in buffer
        strcpy(buffer, "Hello world\n");

        socklen = sizeof(struct sockaddr_in);
        //send packet to socket
        saddr.sin_port = htons(4096);
        status = sendto(sock, buffer, strlen(buffer), 0, (struct sockaddr *)&saddr, socklen);

        saddr.sin_port = htons(4097);
        status = sendto(sock, buffer, strlen(buffer), 0, (struct sockaddr *)&saddr, socklen);
    }

    shutdown(sock, 2);
    close(sock);

    return (EXIT_SUCCESS);
}

